// node 28_字符串中出现次数最多的字符.js

//Map和object对比
// Map空间复杂度低于object,相同内存下Map能多存储%50的键值对
// 涉及大量插入操作，Map性能更高
// 涉及大量查找操作，选择objct更好一些
// 涉及大量删除操作，Map性能更高

//lastIndexOf() 在数组中查找元素返回最后一次出现的索引 

let s = 'asabbbada'

//方法1
//Map
function operateString(params) {
    let map = new Map()
    let max = 0
    let res = null
    params.split('').forEach(item => {//转数组后使用了forEach遍历
        if(!map.get(item)) map.set(item,0)
        map.set(item,map.get(item)+1)
        if(map.get(item) >= max){
            res = item
            max = map.get(item)
        } 
    });
    console.log(map)
    return `出现次数最多的字符是${res},出现了${max}次。`
}
console.log(operateString(s))

//方法2
//使用对象存储
function operateString2(params) {
    let obj = {}
    let max = 0
    let res = null
    for(let i = 0 ; i < params.length ; i++){//使用for循环遍历
        if(!obj[params[i]]) obj[params[i]] = 0
        obj[params[i]]++
        if(obj[params[i]]>max){
            res = params[i]
            max = obj[params[i]]
        }
    }
    console.log(obj)
    return `出现次数最多的字符是${res},出现了${max}次。`
}
console.log(operateString2(s))

//方法3
//转数组-排序-使用lastIndexOf()和indexOf()进行操作
function operateString3(params) {
    let max = 0
    let res = null
    let newS = params.split('').sort()

    //遍历实现1
    for(let i=0;i<newS.length;i++){
        let long = newS.lastIndexOf(newS[i])-newS.indexOf(newS[i])+1
        if(long > max){
            max = long
            res = newS[i]
        }
        i = newS.lastIndexOf(newS[i]) //重定位i的值
    }

    //遍历实现2
    // new Set(newS).forEach(i=>{
    //     let long = newS.lastIndexOf(i)-newS.indexOf(i)+1
    //     if(long > max){
    //         max = long
    //         res = i
    //     }
    // })

    console.log(newS)
    return `出现次数最多的字符是${res},出现了${max}次。`
}
console.log(operateString3(s))

//方法4
//把字符使用replace依次替换为空，通过比较前后字符串长度来确定字符数量
function operateString4(params) {
    let max = 0
    let res = null
    while(params){
        let long = params.length
        let value = params[0]//找到每次要匹配替换的字符

        let reg = new RegExp(value,'g')//合成正则表达式
        params = params.replace(reg,'')//将字符替换为空

        let newLong =params.length
        let index = long - newLong//通过比较前后字符串长度来确定字符数量

        if(index > max){
            max = index
            res = value
        }
    }
    console.log(params)
    return `出现次数最多的字符是${res},出现了${max}次。`
}
console.log(operateString4(s))

//方法5
//转数组后使用reduce
function  operateString5(params) {
    let res = params.split('').reduce((pro,item,index,arr)=>{
        if(!pro[item]) pro[item] = 0
        pro[item] += 1
        if(pro[item] > pro['max']){
            pro['max'] = pro[item]
            pro['res'] = item
        }
        return pro
    },{res:null,max:0})
    console.log(res)
    return `出现次数最多的字符是${res['res']},出现了${res['max']}次。`
}
console.log(operateString5(s))